home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 5
/
Skunkware 5.iso
/
src
/
X11
/
wais
/
x
/
qcommands.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-09
|
38KB
|
1,630 lines
/* WIDE AREA INFORMATION SERVER SOFTWARE:
No guarantees or restrictions. See the readme file for the full standard
disclaimer.
This is part of the X user-interface for the WAIS software. Do with it
as you please.
jonathan@Think.COM
*
* $Log: qcommands.c,v $
* Revision 1.24 92/05/07 14:51:22 jonathan
* Changed use of setitimer to alarm. Thanks to
* steinkel@carlisle-emh2.army.mil.
*
* Revision 1.23 92/04/30 12:22:11 jonathan
* Modified to understand "quit no save" and desensitivize it when necessary.
*
* Revision 1.22 92/04/28 15:28:24 jonathan
* Cleaned up use of scrollists. Fixed bugs in double clicking. Added
* ability to view selected sources and relevant documents.
*
* Revision 1.21 92/03/23 16:08:43 jonathan
* Added file requester, save as button, changed some sensitivity, that kind
* of stuff.
*
* Revision 1.20 92/03/17 14:24:17 jonathan
* Added Cursor code, timers, etc. Really a lot of stuff.
*
* Revision 1.19 92/03/06 14:47:16 jonathan
* New and Improved source loading!
*
* Revision 1.18 92/03/02 14:34:20 jonathan
* Added -f to csh call, per blaze@think.com.
*
* Revision 1.17 92/03/01 14:02:08 jonathan
* Modified all calls to PrintStatus to use PrintStatusW for compatibility
* with ui PrintStatus.
*
* Revision 1.16 92/02/17 17:48:27 jonathan
* Moved last_doc to a global, so it can be reset on a new search.
*
*
* Revision 1.15 92/02/17 12:55:38 jonathan
* Added WCAT type to text display. Added RCSid and $Log too.
*
*
*/
/* this file contains X specific code - it is an integral part of XWAIS */
#ifndef lint
static char *RCSid = "$Header: /tmp_mnt/net/quake/proj/wais/wais-8-b5/x/RCS/qcommands.c,v 1.24 92/05/07 14:51:22 jonathan Exp $";
#endif
#define _C_QCOMMANDS
#include "xwais.h"
#include <setjmp.h>
static jmp_buf jbuf;
static Boolean editting_new_question,
busy = FALSE, searching = FALSE,
quit = FALSE, save_question = FALSE;
static int last_doc = NO_ITEM_SELECTED,
last_qdoc = NO_ITEM_SELECTED,
last_source = NO_ITEM_SELECTED;
static XQuestion helpquestion = NULL;
static Textbuff current_text;
/* forward declarations */
static void DoTSaveCB _AP((Widget w,
XtPointer closure,
XtPointer call_data));
static long
GetLineFromPos(text, p)
char *text;
XawTextPosition p;
{
Textbuff t;
long i, lines;
for(lines=0, i=0; (i < p) && (*text != 0); i++, text++)
if(*text == '\n') lines++;
return lines;
}
static XawTextPosition
GetPosFromLine(text, line)
char *text;
long line;
{
Textbuff t;
long i;
XawTextPosition pos;
for(pos=0, i=0; (i < line) && (*text != 0); pos++, text++)
if(*text == '\n') i++;
return pos;
}
static int get_selected_type()
{
return(get_selected_item(typewindow->ListWidget));
}
static int get_selected_qsource(question)
XQuestion question;
{
return(get_selected_item(question->window->Sources->ListWidget));
}
static int get_selected_qdoc(question)
XQuestion question;
{
return(get_selected_item(question->window->RelevantDocuments->ListWidget));
}
static int get_selected_response(question)
XQuestion question;
{
return(get_selected_item(question->window->ResultDocuments->ListWidget));
}
#include <signal.h>
#define TIMEOUT 1
static int new, old; /* timer values */
typedef void (voidfunc)();
static void* alarm_signal;
static void
SetCursors(cursor)
Cursor cursor;
{
QuestionWindow qw = the_Question->window;
static Cursor xterm_cursor = NULL;
if(xterm_cursor == NULL)
xterm_cursor = XCreateFontCursor(CurDpy, XC_xterm);
if(cursor != NULL) {
XDefineCursor(CurDpy, XtWindow(qw->keywordwid), cursor);
XDefineCursor(CurDpy, XtWindow(qw->shell), cursor);
XDefineCursor(CurDpy, XtWindow(qw->Sources->ListWidget), cursor);
XDefineCursor(CurDpy, XtWindow(qw->RelevantDocuments->ListWidget), cursor);
XDefineCursor(CurDpy, XtWindow(qw->ResultDocuments->ListWidget), cursor);
XDefineCursor(CurDpy, XtWindow(qw->StatusWindow), cursor);
}
else {
XDefineCursor(CurDpy, XtWindow(qw->keywordwid), xterm_cursor);
XUndefineCursor(CurDpy, XtWindow(qw->shell));
XUndefineCursor(CurDpy, XtWindow(qw->Sources->ListWidget));
XUndefineCursor(CurDpy, XtWindow(qw->RelevantDocuments->ListWidget));
XUndefineCursor(CurDpy, XtWindow(qw->ResultDocuments->ListWidget));
XUndefineCursor(CurDpy, XtWindow(qw->StatusWindow));
}
}
static void
alarmhandler(sig, code, scp, addr)
long sig, code;
struct sigcontext *scp;
char *addr;
{
XEvent event;
static int cursor = 0;
SetCursors(wais_cursors[cursor]);
cursor = (cursor+1)%NUM_CURSORS;
while((XtAppPending(app_context)&XtIMXEvent) != 0) {
XtAppNextEvent(app_context, &event);
XtDispatchEvent(&event);
}
alarm(new);
return;
}
static void
fuzzButtons()
{
Arg args[1];
XEvent event;
XtSetArg(args[0], XtNsensitive, False);
if(searching) {
XtSetValues(viewbutton, args, ONE);
XtCallActionProc(searchButton, "set", NULL, NULL, 0);
}
else {
XtSetValues(searchButton, args, ONE);
XtCallActionProc(viewbutton, "set", NULL, NULL, 0);
}
XtSetValues(addSourceButton, args, ONE);
XtSetValues(delSourceButton, args, ONE);
XtSetValues(addDocButton, args, ONE);
XtSetValues(delDocButton, args, ONE);
XtSetValues(helpButton, args, ONE);
XtSetValues(saveAsButton, args, ONE);
XtSetValues(doneButton, args, ONE);
XtSetArg(args[0], XtNsensitive, True);
XtSetValues(abortButton, args, ONE);
}
void
unfuzzButtons()
{
Arg args[1];
XEvent event;
XtSetArg(args[0], XtNsensitive, True);
XtSetValues(searchButton, args, ONE);
XtSetValues(addSourceButton, args, ONE);
XtSetValues(delSourceButton, args, ONE);
XtSetValues(addDocButton, args, ONE);
XtSetValues(delDocButton, args, ONE);
XtSetValues(helpButton, args, ONE);
XtSetValues(saveAsButton, args, ONE);
XtSetValues(doneButton, args, ONE);
XtSetValues(viewbutton, args, ONE);
XtSetArg(args[0], XtNsensitive, False);
XtSetValues(abortButton, args, ONE);
}
void
Abort(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
if(busy) {
unfuzzButtons();
longjmp(jbuf, 1);
}
}
/* these are the commands used in the question widget */
/* ARGSUSED */
void
DoSearch(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
Arg args[2];
Question q = the_Question->q;
QuestionWindow qw = the_Question->window;
char message[255];
DocList resdocs = q->ResultDocuments;
double_click = FALSE;
LastClicked = w;
last_doc = -1;
if(busy) return;
/* update the info */
strncpy(q->keywords, GetString(qw->keywordwid), STRINGSIZE);
new = TIMEOUT;
busy = TRUE;
searching = TRUE;
fuzzButtons();
if (setjmp(jbuf) != 0) {
busy = FALSE;
XtCallActionProc(searchButton, "unset", NULL, NULL, 0);
q->ResultDocuments = resdocs;
SetCursors(NULL);
if(q->Sources != NULL) {
SourceList slist;
Source source;
for(slist = q->Sources;
slist != NULL;
slist = slist->nextSource) {
if((source = findsource(slist->thisSource->filename)) != NULL)
close_source(source);
}
}
PrintStatus("\nAbort Search. Question unmodified.");
return;
}
alarm_signal = (void*)signal(SIGALRM, alarmhandler);
old = alarm(new);
SearchWais(q);
alarm(old);
signal(SIGALRM, alarm_signal);
SetCursors(NULL);
freeDocList(resdocs);
busy = FALSE;
unfuzzButtons();
XtSetArg(args[0], XtNsensitive, False);
XtSetArg(args[1], XtNlabel, " View ");
XtSetValues(viewbutton, args, TWO);
XtSetValues(saveAsButton, args, ONE);
XtCallActionProc(searchButton, "unset", NULL, NULL, 0);
the_Question->Result_Items = buildDocumentItemList(q->ResultDocuments, TRUE);
RebuildListWidget(qw->ResultDocuments, the_Question->Result_Items);
}
void
SaveQuestion(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
Arg args[5];
Position x, y;
Dimension width, height;
Cardinal n;
static char** files;
n = 0;
XtSetArg(args[0], XtNwidth, &width); n++;
XtSetArg(args[1], XtNheight, &height); n++;
XtGetValues(top, args, n);
XtTranslateCoords(top, (Position) (width / 2), (Position) (height / 2),
&x, &y);
n = 0;
XtSetArg(args[n], XtNx, MAX(x-150, 0)); n++;
XtSetArg(args[n], XtNy, y); n++;
if(savelist == NULL)
savelist = MakeSaveRequester(top);
XtSetValues(savereq, args, n);
ReplaceText(dirnamewidget, app_resources.questionDirectory);
ReplaceText(filenamewidget, the_Question->q->name);
SetDir(NULL, NULL, NULL);
save_question = TRUE;
XtSetArg(args[0], XtNsensitive, True);
XtSetValues(quitbutton, args, ONE);
XtSetArg(args[0], XtNlabel, "Save&Quit");
XtSetValues(savebutton, args, ONE);
XtAddCallback(savebutton, XtNcallback, DoSave, NULL);
XtAddCallback(quitbutton, XtNcallback, DontSave, NULL);
XtPopup(savereq, XtGrabNone);
}
/* ARGSUSED */
void CloseQuestionEdit(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
char filename[STRINGSIZE];
strncpy(the_Question->q->keywords,
GetString(the_Question->window->keywordwid),
STRINGSIZE);
if(strcmp(the_Question->q->name, "New Question") == 0) {
quit = TRUE;
SaveQuestion(NULL, NULL, NULL);
}
else {
sprintf(filename, "%s%s", app_resources.questionDirectory,
the_Question->q->name);
WriteQuestion(filename, the_Question->q);
exit(0);
}
}
static int get_question_response(questionwindow)
QuestionWindow questionwindow;
{
return(get_selected_item(questionwindow->ResultDocuments->ListWidget));
}
/* ARGSUSED */
void
AddResponseToQuestion(w, closure, call_data)
Widget w;
caddr_t closure, call_data;
{
int numdocs, document_number, i;
Question q = the_Question->q;
QuestionWindow qw = the_Question->window;
DocList this, last;
float top, shown;
double_click = FALSE;
LastClicked = w;
document_number = get_question_response(qw);
if(document_number == NO_ITEM_SELECTED) {
PrintStatusW("\nNo selected response. Select one and try again.",
qw->StatusWindow);
return;
}
/* find and add document to question's relevant documents */
last = findLast(q->RelevantDocuments);
for(this = q->ResultDocuments, i = 0; i < document_number; i++)
this = this->nextDoc;
if(last != NULL)
last->nextDoc = makeDocList(copy_docid(this->thisDoc), NULL);
else q->RelevantDocuments = makeDocList(copy_docid(this->thisDoc), NULL);
if(the_Question->Relevant_Items != NULL)
freeItemList(the_Question->Relevant_Items);
the_Question->Relevant_Items =
buildDocumentItemList(q->RelevantDocuments, FALSE);
q->numdocs = charlistlength(the_Question->Relevant_Items);
RebuildListWidget(qw->RelevantDocuments, the_Question->Relevant_Items);
q->modified = TRUE;
}
/* ARGSUSED */
void
AddDocToQuestion(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
int i;
int SelectedDoc;
Question q = the_Question->q;
QuestionWindow qw = the_Question->window;
float top, shown;
DocumentID docid;
DocList dlist;
if ((SelectedDoc = get_selected_response(the_Question)) == NO_ITEM_SELECTED) {
PrintStatusW("\nNo selected ResultDocument - select one and try again.",
qw->StatusWindow);
return;
}
docid = (DocumentID)s_malloc(sizeof(_DocumentID));
docid->doc = (CRetDocument)s_malloc(sizeof(_CRetDocument));
dlist = makeDocList(docid, NULL);
/* need to get DocID too - that's not as easy. */
docid->doc->headline = the_Question->Result_Items[SelectedDoc];
/* append it to the current sourcelist */
if(q->RelevantDocuments != NULL) {
DocList doc;
for(doc = q->RelevantDocuments; doc->nextDoc != NULL; doc = doc->nextDoc);
doc->nextDoc = dlist;
}
else
q->RelevantDocuments = dlist;
if (the_Question->Relevant_Items != NULL)
freeItemList(the_Question->Relevant_Items);
the_Question->Relevant_Items =
buildDocumentItemList(q->RelevantDocuments, FALSE);
q->numdocs = charlistlength(the_Question->Relevant_Items);
RebuildListWidget(qw->RelevantDocuments, the_Question->Relevant_Items);
}
/* ARGSUSED */
void
DeleteQuestionDoc(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
int i;
float shown;
int SelectedDoc;
Question q = the_Question->q;
QuestionWindow qw = the_Question->window;
DocList doc, last;
if((SelectedDoc = get_selected_qdoc(the_Question)) == NO_ITEM_SELECTED) {
double_click = FALSE;
LastClicked = w;
PrintStatusW("\nNo Document selected. Please select one and try again.",
qw->StatusWindow);
return;
}
/* rip out the bugger */
last_qdoc = NO_ITEM_SELECTED;
q->modified = TRUE;
double_click = FALSE;
LastClicked = NULL;
if (SelectedDoc == 0)
q->RelevantDocuments = q->RelevantDocuments->nextDoc;
else {
for (doc = q->RelevantDocuments, i = 0; i < SelectedDoc-1; i++) {
doc = doc->nextDoc;
}
if(doc->nextDoc != NULL)
doc->nextDoc = doc->nextDoc->nextDoc;
}
if(the_Question->Relevant_Items != NULL) freeItemList(the_Question->Relevant_Items);
the_Question->Relevant_Items = buildDocumentItemList(q->RelevantDocuments, FALSE);
q->numdocs--;
RebuildListWidget(qw->RelevantDocuments, the_Question->Relevant_Items);
}
/* ARGSUSED */
void
PopupSourceMenu(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
Arg args[5];
Position x, y;
Dimension width, height;
Cardinal n;
n = 0;
XtSetArg(args[0], XtNwidth, &width); n++;
XtSetArg(args[1], XtNheight, &height); n++;
XtGetValues(w, args, n);
XtTranslateCoords(w, (Position) 0, (Position)height,
&x, &y);
n = 0;
XtSetArg(args[n], XtNx, x); n++;
XtSetArg(args[n], XtNy, y); n++;
XtSetValues(sshell, args, n);
XawListUnhighlight(sourcewindow->ListWidget);
XtPopup(sshell, XtGrabExclusive);
}
/* ARGSUSED */
void
AddSourceToQuestion(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
int i, snum;
Question q = the_Question->q;
QuestionWindow qw = the_Question->window;
SourceID sid;
SourceList slist;
if((snum = get_selected_source()) != NO_ITEM_SELECTED) {
if(last_source != snum) {
last_source = snum;
}
else {
XtPopdown(sshell);
sid = (SourceID)s_malloc(sizeof(_SourceID));
slist = makeSourceList(sid, NULL);
sid->filename = s_strdup(Source_items[snum]);
/* append it to the current sourcelist */
if(q->Sources != NULL) {
SourceList source;
/* check to see if it's already in the list */
for(source = q->Sources; source != NULL; source = source->nextSource) {
if(strcmp(source->thisSource->filename, sid->filename) == 0) {
s_free(sid);
s_free(slist);
return;
}
if(source->nextSource == NULL) break;
}
source->nextSource = slist;
}
else
q->Sources = slist;
the_Question->Source_Items = buildSourceItemList(q->Sources);
q->numsources = charlistlength(the_Question->Source_Items);
RebuildListWidget(qw->Sources, the_Question->Source_Items);
q->modified = TRUE;
}
}
else XtPopdown(sshell);
}
/* ARGSUSED */
void
EditQuestionSource(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
SList s;
int CurrentSource;
char msg[1000];
Source edit_source = NULL;
double_click = FALSE;
LastClicked = w;
if ((CurrentSource = get_selected_qsource(the_Question))
!= NO_ITEM_SELECTED) {
if (last_source == CurrentSource) {
if((edit_source =
findsource(the_Question->Source_Items[CurrentSource])) == NULL) {
sprintf(msg, "Cant find source: %s\n", the_Question->Source_Items[CurrentSource]);
PrintStatus(msg);
return;
}
else {
sprintf(msg, "Viewing source: %s\n", edit_source->name);
PrintStatus(msg);
PopupSource(edit_source);
}
}
else last_source = CurrentSource;
}
else {
last_source = -1;
XwaisPrintf("No source selected.\nPlease selected one and try again.\n");
}
}
/* ARGSUSED */
void
DeleteQuestionSource(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
int i;
float shown;
int SelectedSource;
Question q = the_Question->q;
QuestionWindow qw = the_Question->window;
SourceList source, last;
if((SelectedSource = get_selected_qsource(the_Question)) == NO_ITEM_SELECTED) {
double_click = FALSE;
LastClicked = w;
PrintStatusW("\nNo source selected. Please select one and try again.",
qw->StatusWindow);
return;
}
/* rip out the bugger */
last_source = NO_ITEM_SELECTED;
q->modified = TRUE;
double_click = FALSE;
LastClicked = NULL;
if (SelectedSource == 0)
q->Sources = q->Sources->nextSource;
else {
for (source = q->Sources, i = 0; i < SelectedSource-1; i++) {
source = source->nextSource;
}
if(source->nextSource != NULL)
source->nextSource = source->nextSource->nextSource;
}
the_Question->Source_Items = buildSourceItemList(q->Sources);
q->numsources--;
RebuildListWidget(qw->Sources, the_Question->Source_Items);
}
static char *
findFilter(type)
char *type;
{
char *p, *i1, *i2, t[80];
static char result[80];
/* filters are of the form TYPE,FILTER;... */
p = app_resources.filters;
while (*p != 0) {
if((i1 = strchr(p, ',')) == NULL) break;
strncpy(t, p, i1-p);
if(!strncmp(t, type, i1-p)) {
if((i2 = strchr(i1, ';')) != NULL) {
strncpy(result, i1+1, i2-i1-1);
result[i2-i1] = 0;
}
else strcpy(result, i1+1);
return result;
}
if((p = strchr(i1, ';')) == NULL) break;
p++;
}
return NULL;
}
static Boolean
tryFilter(t, type, filename)
Textbuff t;
char *type;
char *filename;
{
char fname[STRINGSIZE], command[STRINGSIZE], *text, *viewer;
FILE *fp;
long i;
if((viewer = findFilter(type)) == NULL) return FALSE;
sprintf(fname, "%s%s",
app_resources.documentDirectory,
get_filename(t->docid->doc->headline));
if((fp = fopen(fname, "w")) == NULL) {
sprintf(command, "Error opening file: %s.", fname);
PrintStatusW(command, the_Question->window->StatusWindow);
return;
}
dumptext(fp, t->text, t->size);
fclose(fp);
KillText(t);
sprintf(command, "\nRunning '%s %s'", viewer, fname);
PrintStatusW(command, the_Question->window->StatusWindow);
sprintf(command, "csh -fc '%s %s;/bin/rm %s' &", viewer, fname, fname);
system(command);
return TRUE;
}
static void
DoSource(t)
Textbuff t;
{
char f[STRINGSIZE], message[STRINGSIZE];
FILE *fp;
sprintf(f, "/tmp/src%d", getpid());
if((fp = fopen(f, "w")) == NULL) {
sprintf(message, "\nError opening file: %s.", f);
PrintStatusW(message, the_Question->window->StatusWindow);
return;
}
fprintf(fp, t->text);
fclose(fp);
if((fp = fopen(f, "r")) == NULL) {
sprintf(message, "\nError opening file: %s.", f);
PrintStatusW(message, the_Question->window->StatusWindow);
return;
}
memset(the_Source, 0, sizeof(_Source));
ReadSource(the_Source, fp);
fclose(fp);
if (the_Source->name != NULL) s_free(the_Source->name);
the_Source->name = s_strdup(get_filename(t->docid->doc->headline));
unlink(f);
PopupSource(the_Source);
}
static void do_other_thing(t, type)
Textbuff t;
char *type;
{
Arg args[5];
Position x, y;
Dimension width, height;
Cardinal n;
char message[STRINGSIZE];
if (type != NULL && type[0] != 0) {
sprintf(message,
"\nDocument is of type: %s, which is unknown. Using Save routine.",
type);
PrintStatusW(message, the_Question->window->StatusWindow);
}
n = 0;
XtSetArg(args[0], XtNwidth, &width); n++;
XtSetArg(args[1], XtNheight, &height); n++;
XtGetValues(the_Question->window->shell, args, n);
XtTranslateCoords(the_Question->window->shell, (Position) (width / 2), (Position) (height / 2),
&x, &y);
n = 0;
XtSetArg(args[n], XtNx, MAX(x-150, 0)); n++;
XtSetArg(args[n], XtNy, y); n++;
current_text = t;
if(savelist == NULL)
savelist = MakeSaveRequester(top);
XtSetValues(savereq, args, n);
ReplaceText(filenamewidget, "");
ReplaceText(dirnamewidget, app_resources.documentDirectory);
SetDir(NULL, NULL, NULL);
save_question = FALSE;
XtPopup(savereq, XtGrabNone);
clearReqButtons();
XtRemoveAllCallbacks(savebutton, XtNcallback);
XtAddCallback(savebutton, XtNcallback, DoTSaveCB, t);
}
static boolean
GetDoc(doc, type, textstruct)
DocumentID doc;
char* type;
Textbuff textstruct;
{
Question q = the_Question->q;
new = TIMEOUT;
busy = TRUE;
searching = FALSE;
fuzzButtons();
if (setjmp(jbuf) != 0) {
busy = FALSE;
XtCallActionProc(viewbutton, "unset", NULL, NULL, 0);
SetCursors(NULL);
if(q->Sources != NULL) {
SourceList slist;
Source source;
for(slist = q->Sources;
slist != NULL;
slist = slist->nextSource) {
if((source = findsource(slist->thisSource->filename)) != NULL)
close_source(source);
}
}
KillText(textstruct);
PrintStatus("\nRetrieval aborted.");
return(false);
}
alarm_signal = (void*)signal(SIGALRM, alarmhandler);
old = alarm(new);
textstruct->text = GetWaisDocument(q, doc, type, NULL, &textstruct->size);
alarm(old);
signal(SIGALRM, alarm_signal);
busy = FALSE;
unfuzzButtons();
XtCallActionProc(viewbutton, "unset", NULL, NULL, 0);
SetCursors(NULL);
return(true);
}
static void
ViewDoc(doc, type, size, savep)
DocumentID doc;
char *type;
long size;
Boolean savep;
{
Arg args[5];
Cardinal num_args;
static long request_length = 0;
static int document_number;
WAISDocumentText *text;
char *viewtext, message[255];
int i;
Question q = the_Question->q;
QuestionWindow qw = the_Question->window;
Textbuff textstruct;
TextList thisText, a_tList;
if((textstruct = findTextDoc(doc, type)) != NULL) {
if(textstruct->shell != NULL) {
XtPopdown(textstruct->shell);
XtPopup(textstruct->shell, XtGrabNone);
}
return;
}
if(busy) return;
if(NULL == (thisText = NewText())) {
PrintStatus("\nUnable to allocate Text structure. Bummer.");
return;
}
textstruct = thisText->thisText;
textstruct->size = size;
if(savep)
textstruct->type = s_strdup("WaIsOddBall");
else
textstruct->type = s_strdup(type);
if(GetDoc(doc, type, textstruct) &&
textstruct->text != NULL) {
textstruct->docid = doc;
if(textstruct->size == 0) {
KillText(textstruct);
PrintStatus("\nNo data returned");
sleep(2);
return;
}
if(savep)
do_other_thing(textstruct, NULL);
else if(tryFilter(textstruct, type))
return;
else if (type == NULL ||
substrcmp(type, "TEXT") ||
!strcmp(type, "WCAT")) {
textstruct->textwindow = MakeTextPopup(top, textstruct, doc->doc->headline);
num_args = 0;
XtSetArg(args[num_args], XtNtype, XawAsciiString); num_args++;
XtSetArg(args[num_args], XtNstring, textstruct->text); num_args++;
XtSetValues(textstruct->textwindow, args, num_args);
if (doc->doc->best > 0)
XawTextSetInsertionPoint(textstruct->textwindow,
GetPosFromLine(textstruct->text, doc->doc->best));
XawTextDisplay(textstruct->textwindow);
}
else if (!strcmp(type, "WSRC")) {
DoSource(textstruct);
}
else do_other_thing(textstruct, type);
}
}
static void PopupTypeMenu(w, doc)
Widget w;
DocumentID doc;
{
char** types = doc->doc->type;
int i;
Arg args[5];
Position x, y;
Dimension width, height;
Cardinal n;
n = 0;
XtSetArg(args[0], XtNwidth, &width); n++;
XtSetArg(args[1], XtNheight, &height); n++;
XtGetValues(w, args, n);
XtTranslateCoords(w, (Position) 0, (Position)height,
&x, &y);
n = 0;
XtSetArg(args[n], XtNx, x); n++;
XtSetArg(args[n], XtNy, y); n++;
XtSetValues(typeshell, args, n);
for(i = 0; types[i] != NULL; i++)
Type_items[i] = types[i];
RebuildListWidget(typewindow, Type_items);
XtPopup(typeshell, XtGrabExclusive);
}
void doType(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
long tnum, dnum, size = -1;
DocumentID doc;
if((tnum = get_selected_type()) != NO_ITEM_SELECTED) {
XtPopdown(typeshell);
dnum = get_selected_response(the_Question);
if((doc = findDoc(the_Question->q->ResultDocuments, dnum)) != NULL)
ViewDoc(doc, Type_items[tnum], size, false);
}
else
XtPopdown(typeshell);
}
/* ARGSUSED */
void
ViewResponse(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
Arg args[2];
static int document_number;
Question q = the_Question->q;
QuestionWindow qw = the_Question->window;
DocumentID doc;
Boolean savep;
double_click = FALSE;
LastClicked = w;
if(busy) return;
if(w == saveAsButton)
savep = true;
else
savep = false;
document_number = get_selected_response(the_Question);
if(document_number == NO_ITEM_SELECTED) {
PrintStatusW("\nNo selected response. Select one and try again.",
qw->StatusWindow);
return;
}
if((doc = findDoc(q->ResultDocuments, document_number)) == NULL) {
PrintStatusW("\nUnable to find document. This should not happen.",
qw->StatusWindow);
return;
}
if (document_number != last_doc) {
XtSetArg(args[0], XtNsensitive, True);
if((w != viewbutton) && (doc->doc->type[1] != NULL)) {
XtSetArg(args[1], XtNlabel, "View...");
}
else {
XtSetArg(args[1], XtNlabel, " View ");
}
XtSetValues(viewbutton, args, TWO);
XtSetValues(saveAsButton, args, ONE);
last_doc = document_number;
return;
}
if((w == viewbutton) && (doc->doc->type[1] != NULL)) {
PopupTypeMenu(w, doc);
}
else ViewDoc(doc, doc->doc->type[0], 0, savep);
}
/* ARGSUSED */
void
ViewRelevant(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
int document_number;
Question q = the_Question->q;
QuestionWindow qw = the_Question->window;
DocumentID doc;
double_click = FALSE;
LastClicked = w;
if(busy) return;
document_number = get_selected_qdoc(the_Question);
if(document_number == NO_ITEM_SELECTED) {
PrintStatusW("\nNo selected response. Select one and try again.",
qw->StatusWindow);
return;
}
if((doc = findDoc(q->RelevantDocuments, document_number)) == NULL) {
PrintStatusW("\nUnable to find document. This should not happen.",
qw->StatusWindow);
return;
}
if (document_number != last_qdoc) {
last_qdoc = document_number;
return;
}
ViewDoc(doc, doc->doc->type[0], 0, false);
}
void
EndText(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
Textbuff t;
t = findText(w);
if(t != NULL) {
XtPopdown(t->shell);
KillText(t);
}
}
static Widget helpwindow = NULL;
void EndHelp(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
XtPopdown(helpwindow);
}
void XwaisHelp(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
Widget textwindow, frame, button;
Arg arglist[10];
Cardinal num_args;
static String items[] = {NULL};
if (helpwindow == NULL) {
num_args = 0;
XtSetArg(arglist[num_args], XtNtitle, "X WAIS Help"); num_args++;
XtSetArg(arglist[num_args], XtNiconName, "X WAIS Help"); num_args++;
helpwindow = XtCreatePopupShell("textpopup", applicationShellWidgetClass,
XtParent(w), arglist, num_args);
frame =
XtCreateManagedWidget("helppopupform", formWidgetClass,
helpwindow, NULL, ZERO);
num_args = 0;
XtSetArg(arglist[num_args], XtNtype, XawAsciiFile); num_args++;
XtSetArg(arglist[num_args], XtNstring, app_resources.helpFile); num_args++;
XtSetArg(arglist[num_args], XtNeditType, XawtextRead); num_args++;
textwindow =
XtCreateManagedWidget("textWindow", asciiTextWidgetClass, frame, arglist, num_args);
button = MakeCommandButton(frame, "tdone", EndHelp,
textwindow, NULL, NULL);
SettIcon(helpwindow);
}
XtPopup(helpwindow, XtGrabNone);
}
#include <X11/Xaw/TextP.h>
static XawTextPosition
findstring(text, string, casesensitive)
char *text, *string;
Boolean casesensitive;
{
char *t, *t2, *t3;
if (casesensitive) {
for (t = text; *t != 0; t++) {
if (*t == *string) {
t2 = t;
t3 = string;
do {
t2++;
t3++;
if(*t3 == 0) return((XawTextPosition)(t-text));
}
while(*t2 == *t3);
}
}
return -1;
}
else {
for (t = text; *t != 0; t++) {
if (tolower(*t) == tolower(*string)) {
t2 = t;
t3 = string;
do {
t2++;
t3++;
if(*t3 == 0) return((XawTextPosition)(t-text));
}
while(tolower(*t2) == tolower(*t3));
}
}
return -1;
}
}
/* ARGSUSED */
void
showKeyword(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
Question q = the_Question->q;
QuestionWindow qw = the_Question->window;
Textbuff t;
static char msg[STRINGSIZE], str[STRINGSIZE], minstr[STRINGSIZE], *keys;
Widget tw;
XawTextPosition minpos, pos, pos2, offset;
XawTextBlock text;
int i, j, k;
char c1, c2;
if((t = findText(w)) == NULL) {
XwaisPrintf("couldn't find text.\n");
return;
}
keys = q->keywords;
tw = t->textwindow;
minpos = 999999;
minstr[0] = 0;
sprintf(msg, "\nSearching for next keyword...");
PrintStatusW(msg, t->status);
/* parse the keywords into individual words */
for(j = 0, i = 0; i <= strlen(keys); i++) {
str[j] = keys[i];
if ((keys[i] == 0) || (keys[i] == ' ') || (keys[i] == '\n')) {
str[j] = 0;
j = 0;
text.ptr = str;
text.length = strlen(str);
text.firstPos = 0;
text.format = FMT8BIT;
for(offset = XawTextGetInsertionPoint(tw),
pos = findstring(t->text+offset, str, FALSE);
pos > 0;
offset=pos+1,
pos = findstring(t->text+offset, str, FALSE)) {
pos+=offset;
c1 = t->text[pos-1];
c2 = t->text[pos+text.length];
if((isspace(c1) || ispunct(c1)) &&
(isspace(c2) || ispunct(c2))) {
if (pos < minpos) {
minpos = pos;
strcpy(minstr, str);
break;
}
}
}
}
else
j++;
}
if (minpos == 999999) {
sprintf( msg, "\nCould not find any more keywords.");
XawTextUnsetSelection(tw);
PrintStatusW(msg, t->status);
return;
}
else {
XawTextSetInsertionPoint( tw, minpos + strlen(minstr));
sprintf(msg, "\nSearching for next keyword...done");
PrintStatusW(msg, t->status);
XawTextSetSelection( tw, minpos, minpos + strlen(minstr));
return;
}
}
void
SaveText(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
Arg args[5];
Position x, y;
Dimension width, height;
Cardinal n;
Textbuff t;
if((t = findText(w)) == NULL) {
XwaisPrintf("couldn't find text.\n");
return;
}
n = 0;
XtSetArg(args[0], XtNwidth, &width); n++;
XtSetArg(args[1], XtNheight, &height); n++;
XtGetValues(t->textwindow, args, n);
XtTranslateCoords(t->textwindow, (Position) (width / 2), (Position) (height / 2),
&x, &y);
n = 0;
XtSetArg(args[n], XtNx, MAX(x-150, 0)); n++;
XtSetArg(args[n], XtNy, y); n++;
current_text = t;
if(savelist == NULL)
savelist = MakeSaveRequester(top);
XtSetValues(savereq, args, n);
ReplaceText(filenamewidget, "");
ReplaceText(dirnamewidget, app_resources.documentDirectory);
SetDir(NULL, NULL, NULL);
save_question = FALSE;
XtPopup(savereq, XtGrabNone);
clearReqButtons();
XtRemoveAllCallbacks(savebutton, XtNcallback);
XtAddCallback(savebutton, XtNcallback, DoTSaveCB, t);
}
void
DoSave(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
FILE *fp;
char message[STRINGSIZE], filename[STRINGSIZE];
Arg arglist[10];
Cardinal num_args;
XtPopdown(savereq);
clearReqButtons();
if(save_question) {
strncpy(the_Question->q->name, GetString(filenamewidget), STRINGSIZE);
sprintf(filename, "%s/%s",
GetString(dirnamewidget), the_Question->q->name);
WriteQuestion(filename, the_Question->q);
if(quit)
exit(0);
else {
char name[STRINGSIZE];
num_args = 0;
sprintf(name, "X WAIS Question: %s", the_Question->q->name);
XtSetArg(arglist[num_args], XtNtitle, name); num_args++;
XtSetArg(arglist[num_args], XtNiconName, the_Question->q->name); num_args++;
XtSetValues(top, arglist, num_args);
}
}
else {
DoTSave(w, closure, call_data);
}
}
void
DontSave(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
XtPopdown(savereq);
clearReqButtons();
if(quit)
exit(0);
}
void
DoTSave(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
DoTSaveCB(w, (XtPointer)current_text, NULL);
}
static void
DoTSaveCB(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
FILE *fp;
char message[STRINGSIZE], filename[STRINGSIZE];
Textbuff t = (Textbuff) closure;
strncpy(filename, GetString(filenamewidget), STRINGSIZE);
if(filename[0]==0) {
PrintStatusW("\nYou have to enter a filename.",
the_Question->window->StatusWindow);
return;
}
XtPopdown(savereq);
clearReqButtons();
if (filename[0] != '/') {
if(t->type != NULL &&
!strcmp(t->type, "WSRC"))
sprintf(message, "%s%s", app_resources.userSourceDirectory, filename);
else
sprintf(message, "%s%s", GetString(dirnamewidget), filename);
strcpy(filename, message);
}
if((fp = fopen(filename, "w")) == NULL) {
sprintf(message, "\nUnable to save %s.", filename);
PrintStatusW(message, the_Question->window->StatusWindow);
}
else {
dumptext(fp, t->text, t->size);
fclose(fp);
}
if(t->type != NULL && strcmp(t->type, "TEXT") != 0)
KillText(t);
}
void
DontTSave(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
XtPopdown(savereq);
clearReqButtons();
}
void
setSourceMenu()
{
/*
SList s;
Widget entry;
if(sourcemenu)
XtDestroyWidget(sourcemenu);
sourcemenu = XtCreatePopupShell("menu", simpleMenuWidgetClass, sourcebutton,
NULL, ZERO);
for (s = Sources; s != NULL; s = s->nextSource) {
char * item = s->thisSource->name;
entry = XtCreateManagedWidget(item, smeBSBObjectClass, sourcemenu,
NULL, ZERO);
XtAddCallback(entry, XtNcallback, AddSourceToQuestion, NULL);
}
*/
}
void
addSection(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
int i;
Question q = the_Question->q;
QuestionWindow qw = the_Question->window;
float top, shown;
DocList dlist;
DocumentID doc;
XawTextPosition p1, p2;
long l1, l2;
Textbuff t;
t = findText(w);
XawTextGetSelectionPos(t->textwindow, &p1, &p2);
if(p1 >= 0 && p2 > 0) {
/* find the line positions */
l1 = GetLineFromPos(t->text, p1);
l2 = GetLineFromPos(t->text, p2);
doc = copy_docid(t->docid);
doc->start = l1;
doc->end = l2;
dlist = makeDocList(doc, NULL);
/* append it to the current rellist */
if(q->RelevantDocuments != NULL) {
DocList doc;
for(doc = q->RelevantDocuments; doc->nextDoc != NULL; doc = doc->nextDoc);
doc->nextDoc = dlist;
}
else
q->RelevantDocuments = dlist;
if(the_Question->Relevant_Items != NULL)
freeItemList(the_Question->Relevant_Items);
the_Question->Relevant_Items =
buildDocumentItemList(q->RelevantDocuments, FALSE);
q->numdocs = charlistlength(the_Question->Relevant_Items);
RebuildListWidget(qw->RelevantDocuments, the_Question->Relevant_Items);
}
}
void
DoSSave(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
FILE *fp;
char name[STRINGSIZE];
Source source;
SList current_sources;
source = the_Source;
XtPopdown(sourcepopup);
strcpy(name, GetString(snamewid));
if(!((strlen(name) > 4) &&
strstr(name, ".src") &&
(!strcmp(".src", strstr(name, ".src")))))
strcat(name, ".src");
if(source->name != NULL) s_free(source->name);
source->name = s_strdup(name);
if (source->maintainer != NULL) s_free(source->maintainer);
source->maintainer = s_strdup(GetString(maintainerwid));
if (source->description != NULL) s_free(source->description);
source->description = s_strdup(GetString(descwid));
strncpy(source->server, GetString(serverwid), STRINGSIZE);
strncpy(source->service, GetString(servicewid), STRINGSIZE);
strncpy(source->database, GetString(dbwid), STRINGSIZE);
strncpy(source->cost, GetString(costwid), STRINGSIZE);
strncpy(source->units, GetString(unitwid), STRINGSIZE);
WriteSource(app_resources.userSourceDirectory, source, TRUE);
NumSources = 0;
GetSourceNames(app_resources.userSourceDirectory);
if(app_resources.commonSourceDirectory[0] != 0)
GetSourceNames(app_resources.commonSourceDirectory);
RebuildListWidget(sourcewindow, Source_items);
}
void
DontSSave(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
XtPopdown(sourcepopup);
}
void showNext(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
Textbuff t;
DocumentID d;
Source source;
Question q = the_Question->q;
t = findText(w);
if(t != NULL) {
if(t->docid->doc != NULL &&
t->docid->doc->sourceID != NULL &&
t->docid->doc->sourceID->filename != NULL)
source = findsource(t->docid->doc->sourceID->filename);
if (source == NULL) {
PrintStatusW("\nCould not find Source for this document!",
t->status);
return;
}
if((d = getNextorPrevDoc(q, source, t->docid, TRUE)) != NULL)
ViewDoc(d, d->doc->type[0], 0, false);
else
PrintStatusW("\nCould not get next document.", t->status);
}
}
void showPrevious(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
Textbuff t;
DocumentID d;
Source source;
t = findText(w);
if(t != NULL) {
if(t->docid->doc != NULL &&
t->docid->doc->sourceID != NULL &&
t->docid->doc->sourceID->filename != NULL)
source = findsource(t->docid->doc->sourceID->filename);
if (source == NULL) {
PrintStatusW("\nCould not find Source for this document!",
t->status);
return;
}
if((d = getNextorPrevDoc(the_Question->q, source, t->docid, FALSE))
!= NULL)
ViewDoc(d, d->doc->type[0], 0, false);
else
PrintStatusW("\nCould not get previous document.", t->status);
}
}
void setFile(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
XtPopdown(savereq);
clearReqButtons();
}
void quitFile(w, closure, call_data)
Widget w;
XtPointer closure, call_data;
{
XtPopdown(savereq);
clearReqButtons();
}